// Shortcuts
var trace = function(message) { YAHOO.log(message, "test"); };
var assert = YAHOO.util.Assert;


flyui.flybasepub.Service.TestData = function() {
	this.FBgn0002828_1 = new flyui.flybasepub.Publication();
	this.FBgn0002828_1.flybaseID = "http://openflydata.org/id/flybase/feature/Drosophila_melanogaster/SO_0000704/FBgn0002828";
	this.FBgn0002828_1.pubID = "http://openflydata.org/id/flybase/pub/FBrf0063411";
	this.FBgn0002828_1.uniquename = "FBrf0063411";
	this.FBgn0002828_1.title = "[New mutants report.]";
	this.FBgn0002828_1.pyear = "1952";
	this.FBgn0002828_1.pages = "60--62";
	this.FBgn0002828_1.volume = "26";
	this.FBgn0002828_1.miniref = "Edmondson, 1952, D. I. S. 26: 60--62";
	this.FBgn0002828_1.author = ["http://openflydata.org/id/flybase/pubauthor/FBrf0063411_1"];
	
	this.FBgn0002828_2 = new flyui.flybasepub.Publication();
	this.FBgn0002828_2.flybaseID = "http://openflydata.org/id/flybase/feature/Drosophila_melanogaster/SO_0000704/FBgn0002828";
	this.FBgn0002828_2.pubID = "http://openflydata.org/id/flybase/pub/FBrf0066905";
	this.FBgn0002828_2.uniquename = "FBrf0066905";
	this.FBgn0002828_2.title = "The Genome of Drosophila melanogaster.";
	this.FBgn0002828_2.pyear = "1992";
	this.FBgn0002828_2.pages = "viii + 1133pp";
	this.FBgn0002828_2.miniref = "Lindsley and Zimm, 1992, The Genome of Drosophila melanogaster. ";
	this.FBgn0002828_2.author = [""];
	
	this.resultSet_FBgn0002828 = {
		"head": {
			"vars": [ "flybaseID" , "pub" , "uniquename" , "title" , "pyear" , "pages", "volume", "miniref" ]
		} ,
		"results": {
			"bindings": [
			{
		        "flybaseID": { "type": "uri" , "value": "http://openflydata.org/id/flybase/feature/Drosophila_melanogaster/SO_0000704/FBgn0002828" } ,
		        "pub": { "type": "uri" , "value": "http://openflydata.org/id/flybase/pub/FBrf0066905" } ,
		        "uniquename": { "datatype": "http://www.w3.org/2001/XMLSchema#string" , "type": "typed-literal" , "value": "FBrf0066905" } ,
		        "title": { "datatype": "http://www.w3.org/2001/XMLSchema#string" , "type": "typed-literal" , "value": "The Genome of Drosophila melanogaster." } ,
		        "pyear": { "datatype": "http://www.w3.org/2001/XMLSchema#string" , "type": "typed-literal" , "value": "1992" } ,
		        "pages": { "datatype": "http://www.w3.org/2001/XMLSchema#string" , "type": "typed-literal" , "value": "viii + 1133pp" } ,
		       "miniref": { "datatype": "http://www.w3.org/2001/XMLSchema#string" , "type": "typed-literal" , "value": "Lindsley and Zimm, 1992, The Genome of Drosophila melanogaster. " } 
		    } ,
		    {
		        "flybaseID": { "type": "uri" , "value": "http://openflydata.org/id/flybase/feature/Drosophila_melanogaster/SO_0000704/FBgn0002828" } ,
		        "pub": { "type": "uri" , "value": "http://openflydata.org/id/flybase/pub/FBrf0063411" } ,
		        "uniquename": { "datatype": "http://www.w3.org/2001/XMLSchema#string" , "type": "typed-literal" , "value": "FBrf0063411" } ,
		        "title": { "datatype": "http://www.w3.org/2001/XMLSchema#string" , "type": "typed-literal" , "value": "[New mutants report.]" } ,
		        "pyear": { "datatype": "http://www.w3.org/2001/XMLSchema#string" , "type": "typed-literal" , "value": "1952" } ,
		        "pages": { "datatype": "http://www.w3.org/2001/XMLSchema#string" , "type": "typed-literal" , "value": "60--62" } ,
		        "miniref": { "datatype": "http://www.w3.org/2001/XMLSchema#string" , "type": "typed-literal" , "value": "Edmondson, 1952, D. I. S. 26: 60--62" }
		    }
			]
		}
	};
};

/**
 * @class
 * A collection of tests to test the module contents.
 */
flyui.flybasepub.Service.ModuleTests = function() {};


/** 
 * Set up function for the flyui.flybasepub ModuleTests.
 */
flyui.flybasepub.Service.ModuleTests.setUpTest = function() {
	try {
		trace("setUp test");
	} catch (e) {
		flyui.err("setUp error, "+e.name+", "+e.message);
	}
};


/** 
 * Tear down function for the flyui.flybasepub ModuleTests.
 */
flyui.flybasepub.Service.ModuleTests.tearDownTest = function() {
	try {
		trace("tearDown test");
	} catch (e) {
		flyui.err("tearDown error, "+e.name+", "+e.message);
	}
};


/** 
 * Test that the contents of the flyui.flybasepub module have been defined.
 */
flyui.flybasepub.Service.ModuleTests.testModuleContents = function() {
	
	flyui.info("Test \"==== flyui.flybasepub.Service ModuleTests :: testModuleContents ====\" started.");
	
	assert.isNotUndefined(flyui.flybasepub, "flyui.flybasepub is undefined");	
	
	assert.isNotUndefined(flyui.flybasepub.Service, "flyui.flybasepub.Service is undefined");	
	
	assert.isNotUndefined(flyui.flybasepub.Publication, "flyui.flybasepub.Publication is undefined");	
		
};


/** 
 * Construct a YUI test case for the flyui.flybasepub ModuleTests.
 * @return a YUI test case
 * @type YAHOO.tool.TestCase
 */
flyui.flybasepub.Service.ModuleTestCase = function() {
	
	var testCase = new YAHOO.tool.TestCase({
		
		name: "=== flyui.flybasepub ModuleTests ===",
		
		setUp : flyui.flybasepub.Service.ModuleTests.setUpTest,
		
		tearDown : flyui.flybasepub.Service.ModuleTests.tearDownTest,
		
		testModuleContents : flyui.flybasepub.Service.ModuleTests.testModuleContents
		
	});
	
	return testCase;
	
};

// ************************************************************
// Publication TESTS
// ************************************************************


/**
 * @class
 * A collection of tests to test the Publication class.
 */
flyui.flybasepub.Service.PublicationTests = function() {};


/** 
 * Set up function.
 */
flyui.flybasepub.Service.PublicationTests.setUpTest = function() {
	try {
		trace("setUp test");
	} catch (e) {
		flyui.err("setUp error, "+e.name+", "+e.message);
	}
};


/** 
 * Tear down function.
 */
flyui.flybasepub.Service.PublicationTests.tearDownTest = function() {
	try {
		trace("tearDown test");
	} catch (e) {
		flyui.err("tearDown error, "+e.name+", "+e.message);
	}
};

flyui.flybasepub.Service.PublicationTests.testPublicationClassDefinition = function(){
	flyui.info("Test \"==== flyui.flybasepub.Service PublicationTests :: testPublicationClassDefinition ====\" started.");
	
	assert.isNotUndefined(flyui.flybasepub.Publication.newInstancesFromSPARQLResults, "newInstancesFromSPARQLResults is undefined");
	
	var publication = new flyui.flybasepub.Publication();
	assert.isNotUndefined(publication.pubID, "publication.pubID is undefined");	
//	assert.isNotUndefined(publication.uniquename, "publication.uniquenapagesme is undefined");
	assert.isNotUndefined(publication.title, "publication.title is undefined");
	assert.isNotUndefined(publication.pyear, "publication.pyear is undefined");
//	assert.isNotUndefined(publication.pages, "publication.pages is undefined");
//	assert.isNotUndefined(publication.volume, "publication.volume is undefined");
//	assert.isNotUndefined(publication.issue, "publication.issue is undefined");
	assert.isNotUndefined(publication.miniref, "publication.miniref is undefined");	
	
};

flyui.flybasepub.Service.TestData.comparePublications = function( expected, actual ) {

	trace("test flybaseID");	
	assert.areEqual(expected.flybaseID, actual.flybaseID, "flybase ID not as expected");
	
	trace("test pubID");	
	assert.areEqual(expected.pubID, actual.pubID, "pubID not as expected");
	
//	trace("test uniquename");	
//	assert.areEqual(expected.uniquename, actual.uniquename, "uniquename not as expected");
//	
	trace("test title");	
	assert.areEqual(expected.title, actual.title, "title not as expected");
	
	trace("test pyear");	
	assert.areEqual(expected.pyear, actual.pyear, "pyear not as expected");
		
//	trace("test volume");	
//	assert.areEqual(expected.volume, actual.volume, "volume not as expected");
//	
//	trace("test pages");	
//	assert.areEqual(expected.pages, actual.pages, "pages not as expected");
//	
//	trace("test issue");	
//	assert.areEqual(expected.issue, actual.issue, "issue not as expected");
//	
	trace("test miniref");	
	assert.areEqual(expected.miniref, actual.miniref, "miniref not as expected");
	
}


flyui.flybasepub.Service.PublicationTests.testNewPublicationsFromSPARQLResults = function(){
	flyui.info("Test \"==== flyui.flybasepub.Service PublicationTests :: testNewPublicationsFromSPARQLResults ====\" started.");

	var testData = new flyui.flybasepub.Service.TestData();
	
	var publications = flyui.flybasepub.Publication.newInstancesFromSPARQLResults(testData.resultSet_FBgn0002828);
	
	assert.areEqual(2, publications.length, "one publication expected");
	
	// ordered by the year
	flyui.flybasepub.Service.TestData.comparePublications(testData.FBgn0002828_2, publications[0]);
	
	flyui.flybasepub.Service.TestData.comparePublications(testData.FBgn0002828_1, publications[1]);	
};

/** 
 * Construct a YUI test case for the flyui.flybasepub Tests.
 * @return a YUI test case
 * @type YAHOO.tool.TestCase
 */
flyui.flybasepub.Service.PublicationTestCase = function() {
	
	var testCase = new YAHOO.tool.TestCase({
		
		name: "=== flyui.flybasepub.Service PublicationTests ===",
		
		setUp : flyui.flybasepub.Service.PublicationTests.setUpTest,
		
		tearDown : flyui.flybasepub.Service.PublicationTests.tearDownTest,
		
		testPublicationClassDefinition : flyui.flybasepub.Service.PublicationTests.testPublicationClassDefinition,
				
		testNewPublicationsFromSPARQLResults : flyui.flybasepub.Service.PublicationTests.testNewPublicationsFromSPARQLResults
				
	});
	
	return testCase;
	
};



// ************************************************************
// SERVICE TESTS
// ************************************************************

// TODO

/**
 * @class
 * Tests for the Service class.
 */
flyui.flybasepub.Service.ServiceTests = function() {};


/** 
 * Set up function.
 */
flyui.flybasepub.Service.ServiceTests.setUpTest = function() {
	try {
		trace("setUp test");
	} catch (e) {
		flyui.err("setUp error, "+e.name+", "+e.message);
	}
};

/** 
 * Tear down function.
 */
flyui.flybasepub.Service.ServiceTests.tearDownTest = function() {
	try {
		trace("tearDown test");
	} catch (e) {
		flyui.err("tearDown error, "+e.name+", "+e.message);
	}
};

flyui.flybasepub.Service.ServiceTests.testServiceClassDefinition = function () {
	flyui.info("Test \"==== flyui.flybasepub.Service ServiceTests :: testServiceClassDefinition ====\" started.");
	
	var service = new flyui.flybasepub.Service();
	assert.isNotUndefined(service.query, "service.query is undefined");	
	assert.isNotUndefined(service.findPubsByUniqueGeneName, "service.findPubsByUniqueGeneName is undefined");	
};

flyui.flybasepub.Service.ServiceTests.testQuery = function(endpointURL, testCase){
	flyui.info("Test \"==== flyui.flybasepub.Service ServiceTests :: testQuery ====\" started.");
		
	var service = new flyui.flybasepub.Service(endpointURL);
	var query = "ASK { ?s ?p ?o }";
	
	var testOnSuccess = function(responseObject) {
		trace("resume test case (success)");
		testCase.resume(function() {
			
			// check status code			
			assert.areEqual(200, responseObject.status);
			
			// try parsing response text as json
			var resultSet = YAHOO.lang.JSON.parse(responseObject.responseText);
			
			// check json content
			assert.isTrue(resultSet["boolean"], "result set not as expected");
		});
	};
	
	var testOnFailure = function(responseObject) {
		trace("resume test case (failure)");
		testCase.resume(function() {
			// force failure
			assert.fail("request failed, status "+responseObject.status + " " +responseObject.statusText);
		});
	};
	
	trace("initiate request");
	service.query(query, testOnSuccess, testOnFailure);
	
	trace("suspend test case (if test runner hangs here, something is wrong)");
	testCase.wait();
};

flyui.flybasepub.Service.ServiceTests.testFindPubsByUniqueGeneName = function(geneName, expectedPublications, endpointURL, testCase) {
	flyui.info("Test \"==== flyui.flybasepub.Service.ServiceTests :: testFindPubsByUniqueGeneName ("+geneName+") ====\" started.");

	var service = new flyui.flybasepub.Service(endpointURL);
	
	var testOnSuccess = function(publications) {
		trace("resume test case (success)");
		testCase.resume(function() {

			trace("testing number of publications found");
			assert.areEqual(expectedPublications.length, publications.length);
			
			trace("compare pub IDs");
			for (var i in expectedPublications) {
				var expected = expectedPublications[i];
				trace("looking for expected publication "+expected.pubID);
				var found = false;
				for (var j in publications) {
					var actual = publications[j];
					if (expected.pubID == actual.pubID) {
						found = true;
						// uncomment following line for full testing (requires populating test data also)
//						flyui.flybase.TestData.compareGenes(expected, actual);
					}
				}
				assert.isTrue(found, "publication "+expected.pubID+" not found in results");
			}

		});
	};
	
	var testOnFailure = function(responseObject) {
		trace("resume test case (failure)");
		testCase.resume(function() {
			// force failure
			assert.fail("request failed, status "+responseObject.status + " " +responseObject.statusText);
		});
	};
	
	trace("initiate request");
	service.findPubsByUniqueGeneName(geneName, testOnSuccess, testOnFailure);
	
	trace("suspend test case (if test runner hangs here, something is wrong)");
	testCase.wait();
	
};


var pause = 500;

/** 
 * Construct a YUI test case for the flyui.flybasepub ServiceTests.
 * @param {String} endpointURL URL of service
 * @return a YUI test case
 * @type YAHOO.tool.TestCase
 */
flyui.flybasepub.Service.ServiceTestCase = function(endpointURL) {
	
	
	var testCase = new YAHOO.tool.TestCase({
		
		name: "=== flyui.flybasepub ServiceTests ===",
		
		setUp : flyui.flybasepub.Service.ServiceTests.setUpTest,
		
		tearDown : flyui.flybasepub.Service.ServiceTests.tearDownTest,
		
		testServiceClassDefinition : flyui.flybasepub.Service.ServiceTests.testServiceClassDefinition,
		
		testQuery : function() {
			flyui.flybasepub.Service.ServiceTests.testQuery(endpointURL, this);
		},

		testFindPubsByUniqueGeneName_FBgn0002828 : function() {
            var runner = this;
            runner.wait(function() {
                // 'FBgn' test case 
                var testData = new flyui.flybasepub.Service.TestData();
                flyui.flybasepub.Service.ServiceTests.testFindPubsByUniqueGeneName("FBgn0002828", [testData.FBgn0002828_1, testData.FBgn0002828_2], endpointURL, runner);
            }, pause);			
		}

	});
	
	return testCase;
	
};


// ************************************************************
// TEST SUITE & RUNNER
// ************************************************************


/** 
 * Construct a YUI test suite for the flyui.flybasepub module.
 * @param {String} endpointURL URL of service
 * @return a YUI test suite
 * @type YAHOO.tool.TestSuite
 */
flyui.flybasepub.Service.TestSuite = function(endpointURL) {
	var suite = new YAHOO.tool.TestSuite("== flyui.flybasepub.Service Test Suite ==");
	
	suite.add(flyui.flybasepub.Service.ModuleTestCase());
	suite.add(flyui.flybasepub.Service.PublicationTestCase());
	suite.add(flyui.flybasepub.Service.ServiceTestCase(endpointURL));
	return suite;
}

/** 
 * Run the flyui.flybasepub test suite.
 * @param {String} endpointURL URL of service
 */
flyui.flybasepub.Service.runTests = function(endpointURL) {
	trace("flyui.flybasepub.Service :: running tests");
	YAHOO.tool.TestRunner.add(flyui.flybasepub.Service.TestSuite(endpointURL));
	YAHOO.tool.TestRunner.run();
}
